package com.giraffe.cloud.socket;

import com.giraffe.cloud.socket.annotation.TcpCustomMessageDecoder;
import com.giraffe.cloud.socket.annotation.TcpCustomMessageEncoder;
import com.giraffe.cloud.socket.annotation.TcpCustomMessageHandler;
import com.giraffe.cloud.socket.service.NettyTcpService;
import com.giraffe.cloud.socket.service.NettyWebsocketService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;

/**
 * @Author ldx
 * @Date 2019/9/29 10:32
 * @Description
 * @Version 1.0.0
 */
@Configuration
@EnableConfigurationProperties({NettyTcpConfigProperties.class,NettyWebsocketConfigProperties.class})
@ConditionalOnProperty(name = "giraffe.cloud.netty.socket.config.enabled", matchIfMissing = true)
public class NettySocketConfigAutoConfiguration {

    private Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    NettyTcpConfigProperties nettyTcpConfigProperties;

    @Autowired
    NettyWebsocketConfigProperties nettyWebsocketConfigProperties;

    private final String RESOURCE_PATTERN = "/**/*.class";

    @Bean
    public NettyTcpService startTcpService(){
        if(!nettyTcpConfigProperties.getEnabled()){
            return null;
        }
        initCustomMessageProperties(nettyTcpConfigProperties);
        logger.info("tcp start>{}",nettyTcpConfigProperties);
        NettyTcpService nettyTcpService = new NettyTcpService(nettyTcpConfigProperties);
        nettyTcpService.start();
        //nettyTcpService.startServer();
        return nettyTcpService;
    }

    @Bean
    public NettyWebsocketService startWebsocketService(){
        if(!nettyWebsocketConfigProperties.getEnabled()){
            return null;
        }
        logger.info("websocket start>{}",nettyWebsocketConfigProperties);
        NettyWebsocketService nettyWebSocketService = new NettyWebsocketService(nettyWebsocketConfigProperties);
        nettyWebSocketService.start();
        return nettyWebSocketService;
    }

    private void initCustomMessageProperties(NettyTcpConfigProperties tcpConfigProperties){

        //
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        try {
            String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                    ClassUtils.convertClassNameToResourcePath(tcpConfigProperties.getCustomScanPackage()) + RESOURCE_PATTERN;
            Resource[] resources = resourcePatternResolver.getResources(pattern);
            //MetadataReader 的工厂类
            MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
            for (Resource resource : resources) {
                //用于读取类信息
                MetadataReader reader = readerFactory.getMetadataReader(resource);
                //扫描到的class
                String classname = reader.getClassMetadata().getClassName();
                Class<?> clazz = Class.forName(classname);
                //判断是否有指定主解
                if(StringUtils.isEmpty(tcpConfigProperties.getCustomMessageDecoder())){
                    TcpCustomMessageDecoder tcpCustomMessageDecoder = clazz.getAnnotation(TcpCustomMessageDecoder.class);
                    if (tcpCustomMessageDecoder != null) {
                        tcpConfigProperties.setCustomMessageDecoder(classname);
                    }
                }
                if(StringUtils.isEmpty(tcpConfigProperties.getCustomMessageEncoder())){
                    TcpCustomMessageEncoder tcpCustomMessageEncoder = clazz.getAnnotation(TcpCustomMessageEncoder.class);
                    if (tcpCustomMessageEncoder != null) {
                        tcpConfigProperties.setCustomMessageEncoder(classname);
                    }
                }
                TcpCustomMessageHandler tcpCustomMessageHandler = clazz.getAnnotation(TcpCustomMessageHandler.class);
                if (tcpCustomMessageHandler != null) {
                    tcpConfigProperties.setCustomMessageHandler(classname);
                }
            }
        } catch (IOException | ClassNotFoundException e) {
        }
    }



}
